#!/usr/bin/env php
<?php
/**************************************************************************
 *
 *   Copyright 2010 American Public Media Group
 *
 *   This file is part of AIR2.
 *
 *   AIR2 is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   AIR2 is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with AIR2.  If not, see <http://www.gnu.org/licenses/>.
 *
 *************************************************************************/

require_once 'app/init.php';
require_once APPPATH.'/../tests/Test.php';
require_once APPPATH.'/../tests/models/TestTank.php';
require_once APPPATH.'/../tests/models/TestSource.php';
require_once 'tank/Discriminator.php';

/**
 * NOTE: these tests are to make sure the tank/tank_sources lock properly
 * when the discriminator runs.  Also makes sure the discriminator won't run
 * on things in the wrong states.
 */

AIR2_DBManager::init();
$conn = AIR2_DBManager::get_master_connection();
plan(35);

$tank = new TestTank();
$tank->tank_user_id = 1;
$tank->tank_type = 'F';
$tank->tank_status = Tank::$STATUS_IMPORTED;
$tank->save();
$d = new Discriminator();
$sources = array();

/* helper function to reset/run a tank */
function run_tank($status, $ids=null) {
    global $tank, $d;
    $tank->refresh();
    $tank->tank_status = $status;
    $tank->save();
    return $d->run($tank->tank_id, $ids);
}

/* helper function to reset tank_sources */
function reset_tank_sources() {
    global $tank, $sources, $conn;

    // clean TankSources
    $conn->execute('delete from tank_source where tsrc_tank_id = ?', array($tank->tank_id));

    // create TankSources
    $tank->refresh(true);
    for ($i=0; $i<5; $i++) {
        if (!isset($sources[$i])) {
            $sources[$i] = new TestSource();
            $sources[$i]->save();
        }
        $tank->TankSource[$i]->tsrc_status = TankSource::$STATUS_NEW;
        $tank->TankSource[$i]->src_id = $sources[$i]->src_id;
    }
    $tank->save();
}


/**********************
 * Test running on an empty tank (haha) ... with various tank_status
 */
$lock = $d->run(-1);
is( $lock, false, 'non-existent tank - lock' );
is( run_tank(Tank::$STATUS_DISCRIMINATED), false, 'status discriminated - lock' );
is( run_tank(Tank::$STATUS_DISCRIMINATING), false, 'status discriminating - lock' );
is( run_tank(Tank::$STATUS_IMPORTING), false, 'status importing - lock' );
is( run_tank(Tank::$STATUS_IMPORT_FAILED), false, 'status import failed - lock' );
is( run_tank(Tank::$STATUS_NEW), false, 'status new - lock' );

is( run_tank(Tank::$STATUS_DISCRIM_ERRORS), true, 'status disc errors - lock' );
is( run_tank(Tank::$STATUS_IMPORTED), true, 'status imported - lock' );
is( $d->conflict_count, 0, 'status-imported - conflict count' );
is( $d->done_count, 0, 'status-imported - done count' );
is( $d->error_count, 0, 'status-imported - error count' );

/**********************
 * Put some stuff in the tank, and test locking
 */
reset_tank_sources();
is( $tank->TankSource[2]->tsrc_status, TankSource::$STATUS_NEW, 'locking 1 - new' );
is( run_tank(Tank::$STATUS_IMPORTED), true, 'locking 1 - lock' );
$tank->refresh(true);
is( $d->conflict_count, 0, 'locking 1 - conflict count' );
is( $d->done_count, 5, 'locking 1 - done count' );
is( $d->error_count, 0, 'locking 1 - error count' );
is( $tank->TankSource[2]->tsrc_status, TankSource::$STATUS_DONE, 'locking 1 - done' );

// should import 0, since everything is done
is( run_tank(Tank::$STATUS_IMPORTED), true, 'locking 2 - lock' );
is( $d->conflict_count, 0, 'locking 2 - conflict count' );
is( $d->done_count, 0, 'locking 2 - done count' );
is( $d->error_count, 0, 'locking 2 - error count' );

// error on id'ing one source
reset_tank_sources();
$tank->TankSource[2]->src_id = 0;
$tank->save();
is( run_tank(Tank::$STATUS_IMPORTED), true, 'locking 3 - lock' );
is( $d->conflict_count, 0, 'locking 3 - conflict count' );
is( $d->done_count, 4, 'locking 3 - done count' );
is( $d->error_count, 1, 'locking 3 - error count' );

// prevent locking with unstable tsrc
reset_tank_sources();
$tank->TankSource[0]->tsrc_status = TankSource::$STATUS_LOCKED; //trip failure
$tank->save();
is( run_tank(Tank::$STATUS_IMPORTED), false, 'locking 4 - lock' );

// set some tsrc_status
$tank->TankSource[0]->tsrc_status = TankSource::$STATUS_DONE; //skip
$tank->TankSource[1]->tsrc_status = TankSource::$STATUS_ERROR; //skip
$tank->TankSource[2]->tsrc_status = TankSource::$STATUS_CONFLICT; //re-run
$tank->save();
is( run_tank(Tank::$STATUS_IMPORTED), true, 'locking 5 - lock' );
is( $d->conflict_count, 0, 'locking 5 - conflict count' );
is( $d->done_count, 3, 'locking 5 - done count' );
is( $d->error_count, 0, 'locking 5 - error count' );


/**********************
 * Test running on subset of tank_sources
 */
reset_tank_sources();
$ids = array($tank->TankSource[0]->tsrc_id, $tank->TankSource[4]->tsrc_id);
is( run_tank(Tank::$STATUS_IMPORTED, $ids), true, 'run subset - lock' );
is( $d->conflict_count, 0, 'run subset - conflict count' );
is( $d->done_count, 2, 'run subset - done count' );
is( $d->error_count, 0, 'run subset - error count' );
$tank->refresh(true);
is( $tank->TankSource[1]->tsrc_status, TankSource::$STATUS_NEW, 'run subset - still new' );

